/* eslint-disable no-unused-vars */
const _ = require('lodash');
const Handlebars = require('handlebars');
const {
  isDartType
} = require('./utils');

/**
 * 过滤并生成可选参数
 * @param {Object} __ob__
 * @returns
 */
function handleConvert (__ob__) {
  const intersection = __ob__.__intersection__;
  Reflect.deleteProperty(__ob__, '__intersection__');

  if (intersection.length >= Object.keys(__ob__).length) {
    return __ob__
  } else {
    const alpha = Object.create(null);
    for (const key in __ob__) {
      if (intersection.includes(key)) {
        alpha[key] = __ob__[key];
      } else {
        alpha[`?${key}`] = __ob__[key];
      }
    }
    return alpha
  }
}

/**
 * 过滤并生成可选参数-前置函数
 * @param {Object} __ob__
 * @param {Object} parameter
 * @returns
 */
function coveringTreatment (__ob__ = Object.create(null), parameter = Object.create(null)) {
  const keys = Object.keys(parameter);
  for (const key in parameter) {
    __ob__[key] = parameter[key];
  }

  if (__ob__.__intersection__) {
    __ob__.__intersection__ = _.intersection(__ob__.__intersection__, keys);
  } else {
    __ob__.__intersection__ = keys;
  }

  return __ob__;
}

function overrideActual (decorations = []) {
  const list = [];
  for (const decorator of decorations) {
    const [prev, next] = decorator.split(' ');
    const ableValue = prev.replace('?', '');

    if (/^List<(\w+)>/g.test(ableValue)) {
      if (isDartType(RegExp.$1)) {
        list.push(`json["${next}"]??[]`);
      } else {
        list.push(`((json["${next}"]??[]) as List).map((v) => ${RegExp.$1}.fromJson(v)).toList()`);
      }
    } else {
      if (isDartType(ableValue)) {
        list.push(`json["${next}"]`);
      } else {
        list.push(`${ableValue}.fromJson(json["${next}"])`);
      }
    }
  }
  return list;
}

function handleCreator (source, classname, ableGenerateValue = {}) {
  const template = Handlebars.compile(source);
  const { parameters = [], decorators = [], intersection } = ableGenerateValue;

  let alphaValue = decorators;
  // 进行可选参数特殊处理
  if (intersection && intersection.length) {
    alphaValue = decorators.map(v => {
      return intersection.includes(v) ? v : v.replace(' ', '? ');
    })
  }

  const data = {
    classname,
    decorators: alphaValue,
    parameters,
    arguments: parameters.map(v => `this.${v}`).join(', '),
    actualParameters: overrideActual(decorators).join(', ')
  };
  return template(data);
}

module.exports = {
  handleConvert,
  overrideActual,
  coveringTreatment,
  handleCreator
}
